/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

var app = angular.module('bayrec', ['ngRoute', 'ui.bootstrap', 'ui.tree']);

app.service('shared', function() {
    var user = null;
    return {
        getUser: function() {
            return user;
        },
        setUser: function(new_user) {
            user = new_user;
        }
    };
});

app.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
                when('/home', {
                    templateUrl: 'components/home.html',
                    controller: 'home_controller'
                }).
                when('/unavailable', {
                    templateUrl: 'components/unavailable.html',
                    controller: 'controller'
                }).
                when('/register', {
                    templateUrl: 'components/register.html',
                    controller: 'login_controller'
                }).
                when('/login', {
                    templateUrl: 'components/login.html',
                    controller: 'login_controller'
                }).
                otherwise({
                    redirectTo: '/home'
                });
    }]);

app.controller("controller", function($scope, $http, $routeParams, $log, $modal, $location) {
    //$scope.service = 'http://localhost:8000';
    $scope.freebase_mql_api = 'https://www.googleapis.com/freebase/v1/mqlread';
    $scope.freebase_topic_api = 'https://www.googleapis.com/freebase/v1/topic';
    $scope.freebase_image_api = 'https://usercontent.googleapis.com/freebase/v1/image';
    $scope.webservice = 'http://localhost:8080/BCBRS/webresources/service';
    $http.get($scope.webservice + '/test').error(function(data, status, headers, config) {
        $location.path('/unavailable');
    });
});

app.controller("login_controller", function($scope, $http, $routeParams, $log, $location, $modal, shared) {
    $scope.invalidpwd = false;
    $scope.today = function() {
        $scope.dob = new Date();
        $scope.maxDate = new Date();
    };
    $scope.today();

    $scope.clear = function() {
        $scope.dob = null;
    };

    $scope.toggleMin = function() {
        $scope.minDate = $scope.minDate ? null : new Date();
    };
    $scope.toggleMin();

    $scope.open = function($event) {
        $event.preventDefault();
        $event.stopPropagation();
        $scope.opened = true;
    };

    $scope.dateOptions = {
        formatYear: 'yy',
        startingDay: 1
    };

    $scope.format = 'dd.MM.yyyy';
    $scope.initDate = new Date('1998-15-20');

    $scope.notReg = function() {
        $location.path('/register');
    };

    $scope.loginUser = function() {
        var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
        if ($scope.username !== undefined && $scope.username !== ''
                && $scope.password !== undefined && $scope.password !== '') {
            // Login routine
            $http({
                url: $scope.webservice + '/login',
                method: 'POST',
                data: $.param({"username": $scope.username, "password": $scope.password}),
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then(function(res) {
                modalInstance.close();
                if (res.status === 200) {
                    shared.setUser(res.data);
                    $location.path('/home');
                } else {
                    console.log("Invalid User");
                }
            });
        } else {
            console.log("Missing data");
        }
    };

    $scope.validate = function() {
        if ($scope.new_password !== $scope.rptd_password) {
            $scope.invalidpwd = true;
        } else {
            $scope.invalidpwd = false;
        }
    };

    $scope.registerUser = function() {
        var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
        var nuser = new Object();
        nuser.username = $scope.new_username;
        nuser.password = $scope.new_password;
        nuser.name = $scope.new_name;
        nuser.country = $scope.country;
        var day = $scope.dob.getUTCDate() < 10 ? "0" + $scope.dob.getUTCDate() : $scope.dob.getUTCDate();
        var month = ($scope.dob.getUTCMonth() + 1) < 10 ? "0" + ($scope.dob.getUTCMonth() + 1) : ($scope.dob.getUTCMonth() + 1);
        nuser.dob = day + "-" + month + "-" + $scope.dob.getUTCFullYear();
        $http({url: $scope.webservice + '/user',
            method: 'POST',
            data: $.param(nuser),
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
                .then(function(res) {
                    modalInstance.close();
                    if (res.status === 200) {
                        nuser.id = res.data;
                        nuser.likeList = [];
                        nuser.dislikeList = [];
                        nuser.explicitInterests = [];
                        nuser.explicitDislikes = [];
                        shared.setUser(nuser);
                        $location.path('/home');
                    } else {
                        console.log("Something went wrong in register");
                    }
                });
    };
});

app.controller("home_controller", function($scope, $http, $sce, $routeParams, $log, $location, $modal, shared) {
    $scope.user = shared.getUser();
    $scope.active_pane = 0;
    $scope.all_recommendations = [];
    $scope.all_interests = [];
    $scope.history = [];
    $scope.cur_video = null;
    $scope.cur_video_annotations = [];
    $scope.cur_interest = null;
    $scope.users_group = [];
    $scope.credentials = {};
    $scope.credentials.username = "";
    $scope.credentials.password = "";

    $scope.getLabelType = function(p) {
        return "label label-" + $scope.getType(p * 100) + " annotation";
    };

    $scope.refreshAll = function() {
        if ($scope.user !== null) {
            var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
            $http.get($scope.webservice + '/recommend/videos/' + $scope.user.id)
                    .then(function(res) {
                        if (res.status !== 200) {
                            console.log("Something went wrong in refresh recommendations");
                            modalInstance.close();
                        } else {
                            $scope.all_recommendations = res.data;
                            console.log(JSON.stringify($scope.all_recommendations));
                            $http.get($scope.webservice + '/recommend/entities/' + $scope.user.id)
                                    .then(function(res) {
                                        modalInstance.close();
                                        if (res.status !== 200) {
                                            console.log("Something went wrong in refresh interests");
                                        } else {
                                            $scope.all_interests = res.data;
                                            $scope.loadThumbnails();
                                        }
                                    });
                        }
                    });
        }
    };

    $scope.getShowName = function(s, n) {
        if (s.length > n) {
            return s.substring(0, n - 3) + "...";
        } else {
            return s;
        }
    };

    $scope.refreshRecommendations = function() {
        console.log("Refreshing recommendations");
        if ($scope.user !== null) {
            var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
            $http.get($scope.webservice + '/recommend/videos/' + $scope.user.id)
                    .then(function(res) {
                        modalInstance.close();
                        if (res.status !== 200) {
                            console.log("Something went wrong in refresh recommendations");
                        } else {
                            $scope.all_recommendations = res.data;
                        }
                    });
        }
    };

    $scope.refreshInterests = function() {
        if ($scope.user !== null) {
            var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
            $http.get($scope.webservice + '/recommend/entities/' + $scope.user.id)
                    .then(function(res) {
                        modalInstance.close();
                        if (res.status !== 200) {
                            console.log("Something went wrong in refresh interests");
                        } else {
                            $scope.all_interests = res.data;
                            $scope.loadThumbnails();
                        }
                    });
        }
    };

    $scope.isAdmin = function() {
        if ($scope.user !== null)
            return $scope.user.id === 3;
        return false;
    };

    $scope.loadUser = function() {
        if ($scope.user !== null) {
            var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
            $http.get($scope.webservice + '/load/' + $scope.user.id)
                    .then(function(res) {
                        modalInstance.close();
                        if (res.status !== 200) {
                            console.log("Something went wrong in loading");
                        } else {
                            $scope.all_recommendations = JSON.parse(res.data.recommendations);
                            $scope.all_interests = JSON.parse(res.data.entities);
                            $scope.loadThumbnails();
                        }
                    });
        }
    };

    $scope.loadThumbnails = function() {

        var freebase_interests = $scope.all_interests.filter(function(el) {
            return 'freebaseId' in el[0];
        });
        var ids = [];
        for (var e in freebase_interests) {
            ids.push("/" + freebase_interests[e][0].freebaseId.replace(".", "/"));
        }

        var query = [{"mid|=": ids, "mid": [], "/common/topic/image": [{"id": null}]}];
        $http.get($scope.freebase_mql_api + '?query=' + JSON.stringify(query))
                .then(function(res) {
                    if (res.status === 200) {
                        var result = res.data.result;
                        for (var el in $scope.all_interests) {
                            $scope.all_interests[el][0].thumbnail = "img/img.png";
                            if ('freebaseId' in $scope.all_interests[el][0]) {
                                var interest_fid = "/" + $scope.all_interests[el][0].freebaseId.replace(".", "/");
                                for (var ob in result) {
                                    var mids = result[ob].mid;
                                    var imgs = result[ob]["/common/topic/image"];
                                    if (mids.indexOf(interest_fid) > -1 && imgs.length > 0) {
                                        $scope.all_interests[el][0].thumbnail = $scope.freebase_image_api + imgs[0].id;
                                    }
                                }
                            }
                        }
                    } else {
                        console.log("Error fetching data from freebase");
                    }
                });
    };

    $scope.getType = function(p) {
        var type;
        if (p < 25) {
            type = 'danger';
        } else if (p < 50) {
            type = 'warning';
        } else if (p < 75) {
            type = 'info';
        } else {
            type = 'success';
        }
        return type;
    };

    $scope.setActivePane = function(i) {
        $scope.active_pane = i;
        for (var k = 0; k < 9; k++) {
            if (document.getElementById("nav" + k) !== null) {
                document.getElementById("nav" + k).className = "nav-li";
            }
        }
        if (i >= 0) {
            document.getElementById("nav" + i).className = "active-nav-li";
        }
    };
    
    $scope.addGroupUser = function(){
        console.log("Credentials: "+$scope.credentials.username+" "+$scope.credentials.password);
        if ($scope.credentials.username !== '' && $scope.credentials.password !== '') {
            var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
            $http({
                url: $scope.webservice + '/login',
                method: 'POST',
                data: $.param({"username": $scope.credentials.username, "password": $scope.credentials.password}),
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then(function(res) {
                modalInstance.close();
                if (res.status === 200) {
                    $scope.users_group.push(res.data);
                    console.log(res.data);
                } else {
                    console.log("Invalid User");
                }
            });
        }
        $scope.credentials = "";
    };
    
    $scope.all_group_recommendations = [];
    
    $scope.refreshGroupRecommendations = function(){
        if ($scope.user !== null) {
            var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
            var grp = $scope.user.id;
            for(var usr in $scope.users_group){
                grp = grp + "," + $scope.users_group[usr].id;
            }
            $http.get($scope.webservice + '/recommend/group/videos?u=' + grp)
                    .then(function(res) {
                        modalInstance.close();
                        if (res.status !== 200) {
                            console.log("Something went wrong in refresh recommendations");
                        } else {
                            $scope.all_group_recommendations = res.data;
                        }
                    });
        }
    };

    if ($scope.user === undefined || $scope.user === null) {
        $location.path('/login');
    }
    $scope.logoutUser = function() {
        var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
        $http.post($scope.webservice + '/logout/' + $scope.user.id)
                .then(function(res) {
                    modalInstance.close();
                    if (res.status === 200) {
                        $location.path('/login');
                    } else {
                        console.log("Something went wrong in logout");
                    }
                });
    };

    $scope.editProfile = function() {
        $scope.edit_user = angular.copy($scope.user);
        $scope.setActivePane(-4);
    };

    $scope.t = true;
    $scope.f = false;

    $scope.editPreferences = function() {
        $scope.edit_user = angular.copy($scope.user);
        console.log(JSON.stringify($scope.edit_user));
        $scope.setActivePane(-3);
    };

    $scope.save = function(src) {
        if (src === 0) {
            var pref = $scope.edit_user.preferences;
            $http({
                url: $scope.webservice + '/preferences',
                method: 'POST',
                data: $.param({"uid": $scope.edit_user.id, "use_threshold": pref.threshold,
                    "vt": pref.thresholdV, "et": pref.thresholdI,
                    "nv": pref.videoN, "ne": pref.interestN}),
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then(function(res) {
                if (res.status !== 200) {
                    console.log("Something went wrong in setting feedback");
                }
            });

        } else {
            console.log("Save user data");
        }
        $scope.user = $scope.edit_user;
        $scope.setActivePane(0);
    };

    $scope.cancel = function() {
        $scope.setActivePane(0);
    };

    $scope.watch = function(video) {
        $http.get($scope.webservice + '/annotations/' + video.id)
                .then(function(res) {
                    if (res.status === 200) {
                        $scope.cur_video = video;
                        $scope.setActivePane(-1);
                        $scope.cur_video_annotations = res.data;
                    } else {
                        console.log("Something went wrong when loading the annotations");
                    }
                });
    };

    $scope.videoURL = function(video) {
        if (video.url)
            return $sce.trustAsResourceUrl(video.url);
        else
            return "img/temp.mp4";
    };

    $scope.posterURL = function(video) {
        if (video.poster)
            return $sce.trustAsResourceUrl(video.poster);
        else
            return "img/video.png";
    };

    $scope.interestURL = function(interest) {
        if (interest.freebaseId) {
            return 'http://www.freebase.com/m/' + interest.freebaseId.replace('m.', '');
        } else {
            return 'http://www.freebase.com';
        }
    };

    $scope.liked = function(e, flag) {
        if (flag) {
            for (var v in $scope.user.likeList) {
                if ($scope.user.likeList[v].id === e.id)
                    return true;
            }
        } else {
            for (var v in $scope.user.explicitInterests) {
                if ($scope.user.explicitInterests[v].id === e.id)
                    return true;
            }
        }

        return false;
    };

    $scope.disliked = function(e, flag) {
        if (flag) {
            for (var v in $scope.user.dislikeList) {
                if ($scope.user.dislikeList[v].id === e.id)
                    return true;
            }
        } else {
            for (var v in $scope.user.explicitDislikes) {
                if ($scope.user.explicitDislikes[v].id === e.id)
                    return true;
            }
        }
        return false;
    };

    $scope.unrated = function(e, flag) {
        return !$scope.disliked(e, flag) && !$scope.liked(e, flag);

    };

    $scope.video_feedback = function(video, like) {
        like ? $scope.user.likeList.push(video) : $scope.user.dislikeList.push(video);
        $http.post($scope.webservice + '/vfeedback/' + $scope.user.id + '/' + $scope.user.ctx.id + '/' + video.id + '/' + like)
                .then(function(res) {
                    if (res.status !== 200) {
                        console.log("Something went wrong in setting feedback");
                    }
                });
    };

    $scope.interest_feedback = function(interest, like) {
        like ? $scope.user.explicitInterests.push(interest) : $scope.user.explicitDislikes.push(interest);
        $http.post($scope.webservice + '/ifeedback/' + $scope.user.id + '/' + $scope.user.ctx.id + '/' + interest.id + '/' + like)
                .then(function(res) {
                    if (res.status !== 200) {
                        console.log("Something went wrong in setting feedback");
                    }
                });
    };

    $scope.forget = function() {
        var modalInstance = $modal.open({
            templateUrl: 'components/message.html',
            controller: ConfirmCtrl,
            resolve: {
                message: function() {
                    return {"title": "Forget the history", "body": "Are you sure you want to delete all your watch history?"};
                }
            }
        });

        modalInstance.result.then(function() {
            $http.post($scope.webservice + '/forget/' + $scope.user.id)
                    .then(function(res) {
                        if (res.status !== 200) {
                            console.log("Something went wrong in forgetting history");
                        } else {
                            $scope.user.likeList = [];
                            $scope.user.dislikeList = [];
                            $scope.user.explicitInterests = [];
                            $scope.user.explicitDislikes = [];
                        }
                    });
        });
    };

    $scope.explore = function(interest) {
        $scope.cur_interest = interest;
        console.log(JSON.stringify($scope.cur_interest));
        $scope.setActivePane(-2);
    };

    $scope.admin_message = "";

    $scope.rebuild = function() {
        $scope.admin_message = "Building...";
        $http.get($scope.webservice + '/build')
                .then(function(res) {
                    if (res.status === 200) {
                        $scope.admin_message = "Build Successful! Compiled Video Base in " + res.data.VB + " and Knowledge Base in " + res.data.KB;
                    } else {
                        $scope.admin_message = "Build failed";
                    }
                });
    };
    
    // *********** Convert flat data into a nice tree ***************
    $scope.getTree = function(data){
        
        // create a name: node map
        var dataMap = data.reduce(function(map, node) {
                map[node.id] = node;
                return map;
        }, {});

        // create the tree array
        var treeData = [];
        
        data.forEach(function(node) {
            // add to parent
            var parent = dataMap[node.parent];
            if (parent) {
                (parent.items || (parent.items = [])).push(node);
            } else {
                treeData.push(node);
            }
        });
        
        return treeData;
    };
    
    $scope.load_ctx = function() {
        $http.get($scope.webservice + '/ctx/' + $scope.user.id)
                        .then(function(res) {
                            if (res.status !== 200) {
                                console.log('Something went wrong');
                            } else {
                                console.log(JSON.stringify(res.data));
                                $scope.list = $scope.getTree(res.data);
                            }
                        });
    };
    
    $scope.list = [];
    $scope.menuOptions = [
            ['Edit', function ($itemScope) {
                $scope.get_name($itemScope, 'Edit');
            }],
            ['Activate', function ($itemScope) {
                $scope.activate($itemScope);
            }],
            ['Add Child', function ($itemScope) {
                $scope.get_name($itemScope, 'Add');
            }]
        ];
        
    $scope.selectedItem = {};

    $scope.options = {
    };
    
    $scope.get_name = function(scope, cmd) {
        var modalInstance = $modal.open({
            templateUrl: 'components/add_or_rename.html',
            controller: AddRenameCtrl,
            resolve: {
                parameters: function() {
                    return {'obj': scope.$modelValue, 'command': cmd};
                }
            }
        });

        modalInstance.result.then(function(given) {
            if(given.cmd === 'Add'){
                $scope.add(scope, given.name);
            } else {
                $scope.edit(scope, given.name);
            }
        });
    };

    $scope.remove = function(scope) {
        scope.remove();
    };
    
    $scope.isActive = function(scope) {
        return (scope.$modelValue.id === $scope.user.ctx.id);    
    };
    
    $scope.edit = function(scope, name) {
        var ctx = scope.$modelValue;
        $http.post($scope.webservice + '/ctx/rename/' + ctx.id + '/' + name)
                        .then(function(res) {
                            if (res.status !== 200) {
                                console.log('Something went wrong');
                            } else {
                                scope.$modelValue.name = name;
                            }
                        });
    };
    
    $scope.add = function(scope, name) {
        var ctx = scope.$modelValue;
        $http.get($scope.webservice + '/ctx/' + ctx.id + '/' + name)
                        .then(function(res) {
                            if (res.status !== 200) {
                                console.log('Something went wrong');
                            } else {
                                (scope.$modelValue.items || (scope.$modelValue.items = [])).push({
                                    id: res.data,
                                    name: name,
                                    items: []
                                });
                            }
                        });
    };

    $scope.toggle = function(scope) {
        scope.toggle();
    };
    
    $scope.activate = function(scope) {
        var nodeData = scope.$modelValue;
        console.log("Activate "+nodeData.name);
        $http.post($scope.webservice + '/ctx/' + $scope.user.id + '/' + nodeData.id)
                        .then(function(res) {
                            if (res.status !== 200) {
                                console.log('Something went wrong');
                            } else {
                                $scope.user.ctx = nodeData;
                            }
                        });
    };

    $scope.newSubItem = function(scope, id, name) {
        var nodeData = scope.$modelValue;
        nodeData.items.push({
            id: id,
            name: name,
            items: []
        });
    };
});

app.controller("vis_controller", function($scope, $http, $routeParams, $log, $location) {
    var width = 1000, height = 570;
    var color = d3.scale.category20();
    var force = d3.layout.force()
            .charge(-10)
            .linkDistance(2)
            .size([width, height]);

    var svg = d3.select("#graph").append("svg")
            .attr("width", width)
            .attr("height", height);

    d3.json("videobase.json", function(error, graph) {
        force.nodes(graph.nodes)
                .links(graph.links)
                .start();

        var link = svg.selectAll(".link")
                .data(graph.links)
                .enter().append("line")
                .attr("class", "link")
                .style("stroke-width", function(d) {
                    return Math.sqrt(d.value);
                });

        var node = svg.selectAll(".node")
                .data(graph.nodes)
                .enter().append("circle")
                .attr("class", "node")
                .attr("r", 2)
                .style("fill", function(d) {
                    return color(d.group);
                })
                .call(force.drag);

        node.append("title")
                .text(function(d) {
                    return d.name;
                });

        force.on("tick", function() {
            link.attr("x1", function(d) {
                return d.source.x;
            })
                    .attr("y1", function(d) {
                        return d.source.y;
                    })
                    .attr("x2", function(d) {
                        return d.target.x;
                    })
                    .attr("y2", function(d) {
                        return d.target.y;
                    });

            node.attr("cx", function(d) {
                return d.x;
            })
                    .attr("cy", function(d) {
                        return d.y;
                    });
        });
    });
});

function CarouselCtrl($scope) {
    $scope.myInterval = 2000;
    var slides = $scope.slides = [];
    $scope.addSlide = function(i) {
        slides.push({
            image: 'img/slide' + i + '.jpg',
            text: "LinkedTV"
        });
    };
    for (var i = 1; i < 6; i++) {
        $scope.addSlide(i);
    }
}

function SearchCtrl($scope, $http, $modal) {
    $scope.keyword = null;
    $scope.search_results = null;
    $scope.type = 0;
    $scope.searched_keyword = null;

    $scope.search = function() {
        $scope.search_results = [];
        var modalInstance = $modal.open({templateUrl: 'components/loading.html', keyboard: false, backdrop: 'static'});
        if ($scope.keyword !== null) {
            $http.get($scope.webservice + '/videos/' + $scope.keyword + '/' + $scope.type)
                    .then(function(res) {
                        modalInstance.close();
                        $scope.searched_keyword = $scope.keyword;
                        if (res.status === 200) {
                            $scope.search_results = res.data;
                        } else {
                            console.log("Something went wrong in search");
                        }
                    });
        } else {
            modalInstance.close();
        }
    };
}

function ConfirmCtrl($scope, $modalInstance, message) {
    $scope.message = message;
    $scope.ok = function() {
        $modalInstance.close();
    };

    $scope.cancel = function() {
        $modalInstance.dismiss();
    };
}

var AddRenameCtrl = function ($scope, $modalInstance, parameters) {

    $scope.data = {edit_name : ""};
    $scope.command = parameters.command;
 
    $scope.add = function () {
        console.log($scope.command+" "+$scope.data.edit_name);
        $modalInstance.close({name: $scope.data.edit_name, cmd: $scope.command});
    };

    $scope.dismiss = function () {
        $modalInstance.dismiss('cancel');
    };
};

app.directive('ngContextMenu', function ($parse) {
    var renderContextMenu = function ($scope, event, options) {
        if (!$) { var $ = angular.element; }
        $(event.currentTarget).addClass('context');
        var $contextMenu = $('<div>');
        $contextMenu.addClass('dropdown clearfix');
        var $ul = $('<ul>');
        $ul.addClass('dropdown-menu');
        $ul.attr({ 'role': 'menu' });
        $ul.css({
            display: 'block',
            position: 'absolute',
            left: event.pageX + 'px',
            top: event.pageY + 'px'
        });
        angular.forEach(options, function (item, i) {
            var $li = $('<li>');
            if (item === null) {
                $li.addClass('divider');
            } else {
                $li.addClass('dropdown-li');
                $li.text(item[0]);
                $li.on('click', function () {
                    $scope.$apply(function() {
                        item[1].call($scope, $scope);
                    });
                });
            }
            $ul.append($li);
        });
        $contextMenu.append($ul);
        $contextMenu.css({
            width: '100%',
            height: '100%',
            position: 'absolute',
            top: 0,
            left: 0,
            zIndex: 9999
        });
        $(document).find('body').append($contextMenu);
        $contextMenu.on("click", function (e) {
            $(event.currentTarget).removeClass('context');
            $contextMenu.remove();
        }).on('contextmenu', function (event) {
            $(event.currentTarget).removeClass('context');
            event.preventDefault();
            $contextMenu.remove();
        });
    };
    return function ($scope, element, attrs) {
        element.on('contextmenu', function (event) {
            $scope.$apply(function () {
                event.preventDefault();
                var options = $scope.$eval(attrs.ngContextMenu);
                if (options instanceof Array) {
                    renderContextMenu($scope, event, options);
                } else {
                    throw '"' + attrs.ngContextMenu + '" not an array';                    
                }
            });
        });
    };
});